package cn.cyh.queue_service.service.impl;

import cn.cyh.queue_service.common.ResultCode;
import cn.cyh.queue_service.exception.BusinessException;
import cn.cyh.queue_service.mapper.QueueMapper;
import cn.cyh.queue_service.mapper.ServiceTypeMapper;
import cn.cyh.queue_service.mapper.StatisticsMapper;
import cn.cyh.queue_service.mapper.WindowMapper;
import cn.cyh.queue_service.model.dto.PageRequest;
import cn.cyh.queue_service.model.dto.PageResult;
import cn.cyh.queue_service.model.dto.StatisticsRequest;
import cn.cyh.queue_service.model.dto.StatisticsResponse;
import cn.cyh.queue_service.model.entity.Queue;
import cn.cyh.queue_service.model.entity.ServiceType;
import cn.cyh.queue_service.model.entity.Statistics;
import cn.cyh.queue_service.model.entity.Window;
import cn.cyh.queue_service.service.StatisticsService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayOutputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 统计服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class StatisticsServiceImpl extends ServiceImpl<StatisticsMapper, Statistics> implements StatisticsService {
    
    private final StatisticsMapper statisticsMapper;
    private final ServiceTypeMapper serviceTypeMapper;
    private final QueueMapper queueMapper;
    private final WindowMapper windowMapper;
    
    @Override
    public List<StatisticsResponse> getDailyStatistics(LocalDate date, Long serviceTypeId) {
        List<Statistics> statisticsList;
        
        if (serviceTypeId != null) {
            // 获取指定业务类型的统计数据
            Statistics statistics = statisticsMapper.selectByDateAndServiceType(date, serviceTypeId);
            statisticsList = statistics != null ? List.of(statistics) : new ArrayList<>();
        } else {
            // 获取所有业务类型的统计数据
            LambdaQueryWrapper<Statistics> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Statistics::getStatDate, date)
                    .orderByDesc(Statistics::getTotalTickets);
            
            statisticsList = list(queryWrapper);
        }
        
        return convertToResponseList(statisticsList);
    }
    
    @Override
    public List<StatisticsResponse> getStatistics(StatisticsRequest request) {
        List<Statistics> statisticsList;
        
        // 验证请求参数
        if (request.getStartDate() == null || request.getEndDate() == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "起止日期不能为空");
        }
        
        if (request.getStartDate().isAfter(request.getEndDate())) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "开始日期不能晚于结束日期");
        }
        
        if ("daily".equals(request.getType())) {
            // 按日统计
            if (request.getServiceTypeId() != null) {
                // 指定业务类型
                statisticsList = statisticsMapper.selectByDateRangeAndServiceType(
                        request.getStartDate(), request.getEndDate(), request.getServiceTypeId());
            } else {
                // 所有业务类型
                statisticsList = statisticsMapper.selectByDateRange(request.getStartDate(), request.getEndDate());
            }
        } else if ("business".equals(request.getType())) {
            // 按业务类型统计，先获取原始数据，再按业务类型汇总
            Map<Long, StatisticsResponse> businessTypeStatistics = getStatisticsByBusinessType(
                    request.getStartDate(), request.getEndDate());
            
            return new ArrayList<>(businessTypeStatistics.values());
        } else if ("window".equals(request.getType())) {
            // 按窗口统计，需要实时计算
            Map<Long, StatisticsResponse> windowStatistics = getStatisticsByWindow(
                    request.getStartDate(), request.getEndDate());
            
            if (request.getWindowId() != null) {
                // 筛选指定窗口
                StatisticsResponse response = windowStatistics.get(request.getWindowId());
                return response != null ? List.of(response) : new ArrayList<>();
            } else {
                return new ArrayList<>(windowStatistics.values());
            }
        } else {
            throw new BusinessException(ResultCode.PARAM_ERROR, "统计类型不支持");
        }
        
        return convertToResponseList(statisticsList);
    }
    
    @Override
    public Map<Long, StatisticsResponse> getStatisticsByBusinessType(LocalDate startDate, LocalDate endDate) {
        // 获取日期范围内的所有统计数据
        List<Statistics> statisticsList = statisticsMapper.selectByDateRange(startDate, endDate);
        
        // 按业务类型分组
        Map<Long, List<Statistics>> groupedByBusinessType = statisticsList.stream()
                .collect(Collectors.groupingBy(Statistics::getServiceTypeId));

        // 计算每个业务类型的汇总统计
        Map<Long, StatisticsResponse> result = new HashMap<>();

        groupedByBusinessType.keySet().forEach(key -> {
            List<Statistics> statistics = groupedByBusinessType.get(key);
            StatisticsResponse statisticsResponse = new StatisticsResponse();
            Statistics data = statistics.get(0);
            statisticsResponse.setServiceTypeId(data.getServiceTypeId());
            statisticsResponse.setTotalTickets(0);
            statisticsResponse.setWaitingCount(0);
            statisticsResponse.setCompletedCount(0);
            statisticsResponse.setNoShowCount(0);
            AtomicLong totalWaitingTime = new AtomicLong(0L);
            AtomicLong totalServiceTime = new AtomicLong();
            statistics.forEach(item -> {
                totalWaitingTime.addAndGet((long) item.getAvgWaitTime() * item.getCompletedCount());
                totalServiceTime.addAndGet((long) item.getAvgServiceTime() * item.getCompletedCount());
                statisticsResponse.setTotalTickets(statisticsResponse.getTotalTickets() + item.getTotalTickets());
                statisticsResponse.setWaitingCount(statisticsResponse.getWaitingCount() + item.getWaitingCount());
                statisticsResponse.setCompletedCount(statisticsResponse.getCompletedCount() + item.getCompletedCount());
                statisticsResponse.setNoShowCount(statisticsResponse.getNoShowCount() + item.getNoShowCount());
            });
            statisticsResponse.setAvgWaitTime(statisticsResponse.getCompletedCount() != 0 ?
                    (int) (totalWaitingTime.get() / statisticsResponse.getCompletedCount()) : 0);
            statisticsResponse.setAvgWaitTime(statisticsResponse.getCompletedCount() != 0 ?
                    (int) (totalServiceTime.get() / statisticsResponse.getCompletedCount()) : 0);
            result.put(key, statisticsResponse);
        });
        

        return result;
    }
    
    @Override
    public Map<Long, StatisticsResponse> getStatisticsByWindow(LocalDate startDate, LocalDate endDate) {
        // 获取所有窗口
        List<Window> windows = windowMapper.selectList(null);
        Map<Long, Window> windowMap = windows.stream()
                .collect(Collectors.toMap(Window::getId, window -> window));
        
        // 获取日期范围内的队列数据
        LocalDateTime startDateTime = LocalDateTime.of(startDate, LocalTime.MIN);
        LocalDateTime endDateTime = LocalDateTime.of(endDate, LocalTime.MAX);
        
        LambdaQueryWrapper<Queue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.between(Queue::getCreateTime, startDateTime, endDateTime)
                .isNotNull(Queue::getWindowId);
        
        List<Queue> queueList = queueMapper.selectList(queryWrapper);
        
        // 按窗口分组
        Map<Long, List<Queue>> groupedByWindow = queueList.stream()
                .filter(q -> q.getWindowId() != null)
                .collect(Collectors.groupingBy(Queue::getWindowId));
        
        // 计算每个窗口的统计数据
        Map<Long, StatisticsResponse> result = new HashMap<>();
        
        for (Map.Entry<Long, List<Queue>> entry : groupedByWindow.entrySet()) {
            Long windowId = entry.getKey();
            List<Queue> windowQueues = entry.getValue();
            
            Window window = windowMap.get(windowId);
            if (window == null) {
                continue;
            }
            
            // 计算统计数据
            int totalTickets = windowQueues.size();
            long completedCount = windowQueues.stream()
                    .filter(q -> "COMPLETED".equals(q.getStatus()))
                    .count();
            long noShowCount = windowQueues.stream()
                    .filter(q -> "NO_SHOW".equals(q.getStatus()))
                    .count();
            
            // 计算平均等待时间和服务时间
            double avgWaitTime = windowQueues.stream()
                    .filter(q -> q.getWaitTime() != null && q.getWaitTime() > 0)
                    .mapToInt(Queue::getWaitTime)
                    .average()
                    .orElse(0);
            
            double avgServiceTime = windowQueues.stream()
                    .filter(q -> q.getServiceTime() != null && q.getServiceTime() > 0)
                    .mapToInt(Queue::getServiceTime)
                    .average()
                    .orElse(0);
            
            // 计算完成率和未到场率
            double completionRate = totalTickets > 0 ? (double) completedCount / totalTickets : 0;
            double noShowRate = totalTickets > 0 ? (double) noShowCount / totalTickets : 0;
            
            // 构建响应对象
            StatisticsResponse response = StatisticsResponse.builder()
                    .windowId(windowId)
                    .windowName(window.getName())
                    .totalTickets(totalTickets)
                    .completedCount((int) completedCount)
                    .completionRate(completionRate)
                    .noShowCount((int) noShowCount)
                    .noShowRate(noShowRate)
                    .avgWaitTime((int) Math.round(avgWaitTime))
                    .avgServiceTime((int) Math.round(avgServiceTime))
                    .build();
            
            result.put(windowId, response);
        }
        
        return result;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int generateDailyStatistics(LocalDate date) {
        // 获取所有业务类型
        List<ServiceType> serviceTypes = serviceTypeMapper.selectList(null);
        
        // 获取指定日期的队列数据
        LocalDateTime startDateTime = LocalDateTime.of(date, LocalTime.MIN);
        LocalDateTime endDateTime = LocalDateTime.of(date, LocalTime.MAX);
        
        LambdaQueryWrapper<Queue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.between(Queue::getCreateTime, startDateTime, endDateTime);
        
        List<Queue> queueList = queueMapper.selectList(queryWrapper);
        
        // 按业务类型分组
        Map<Long, List<Queue>> groupedByType = queueList.stream()
                .collect(Collectors.groupingBy(Queue::getServiceTypeId));
        
        int count = 0;
        
        // 为每个业务类型生成统计数据
        for (ServiceType serviceType : serviceTypes) {
            List<Queue> typeQueues = groupedByType.getOrDefault(serviceType.getId(), new ArrayList<>());
            
            // 统计数据
            int totalTickets = typeQueues.size();
            if (totalTickets == 0) {
                continue; // 跳过没有数据的业务类型
            }
            
            long completedCount = typeQueues.stream()
                    .filter(q -> "COMPLETED".equals(q.getStatus()))
                    .count();
            
            long noShowCount = typeQueues.stream()
                    .filter(q -> "NO_SHOW".equals(q.getStatus()))
                    .count();
            
            // 计算平均等待时间和服务时间
            double avgWaitTime = typeQueues.stream()
                    .filter(q -> q.getWaitTime() != null && q.getWaitTime() > 0)
                    .mapToInt(Queue::getWaitTime)
                    .average()
                    .orElse(0);
            
            double avgServiceTime = typeQueues.stream()
                    .filter(q -> q.getServiceTime() != null && q.getServiceTime() > 0)
                    .mapToInt(Queue::getServiceTime)
                    .average()
                    .orElse(0);
            
            // 计算高峰时段
            Map<Integer, Long> hourDistribution = typeQueues.stream()
                    .collect(Collectors.groupingBy(q -> q.getCreateTime().getHour(), Collectors.counting()));
            
            int peakHour = hourDistribution.entrySet().stream()
                    .max(Map.Entry.comparingByValue())
                    .map(Map.Entry::getKey)
                    .orElse(0);
            
            // 检查是否已存在该日期和业务类型的统计记录
            Statistics existingStatistics = statisticsMapper.selectByDateAndServiceType(date, serviceType.getId());
            
            if (existingStatistics != null) {
                // 更新现有记录
                existingStatistics.setTotalTickets(totalTickets);
                existingStatistics.setCompletedCount((int) completedCount);
                existingStatistics.setNoShowCount((int) noShowCount);
                existingStatistics.setAvgWaitTime((int) Math.round(avgWaitTime));
                existingStatistics.setAvgServiceTime((int) Math.round(avgServiceTime));
                existingStatistics.setPeakHour(peakHour);
                existingStatistics.setUpdateTime(LocalDateTime.now());
                
                updateById(existingStatistics);
            } else {
                // 创建新记录
                Statistics statistics = Statistics.builder()
                        .statDate(date)
                        .serviceTypeId(serviceType.getId())
                        .totalTickets(totalTickets)
                        .completedCount((int) completedCount)
                        .noShowCount((int) noShowCount)
                        .avgWaitTime((int) Math.round(avgWaitTime))
                        .avgServiceTime((int) Math.round(avgServiceTime))
                        .peakHour(peakHour)
                        .createTime(LocalDateTime.now())
                        .updateTime(LocalDateTime.now())
                        .build();
                
                save(statistics);
            }
            
            count++;
        }
        
        return count;
    }
    
    @Override
    public String exportStatisticsToCSV(StatisticsRequest request) {
        // 获取统计数据
        List<StatisticsResponse> statisticsList = getStatistics(request);
        
        if (CollUtil.isEmpty(statisticsList)) {
            return "日期,业务类型,总票数,已完成数,完成率,未到场数,未到场率,平均等待时间(分钟),平均服务时间(分钟),高峰时段\n";
        }
        
        // 构建CSV内容
        StringBuilder csvContent = new StringBuilder();
        csvContent.append("日期,业务类型,总票数,已完成数,完成率,未到场数,未到场率,平均等待时间(分钟),平均服务时间(分钟),高峰时段\n");
        
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        
        for (StatisticsResponse statistics : statisticsList) {
            csvContent.append(statistics.getStatDate() != null ? statistics.getStatDate().format(dateFormatter) : "")
                    .append(",")
                    .append(StrUtil.isNotBlank(statistics.getServiceTypeName()) ? statistics.getServiceTypeName() : "全部")
                    .append(",")
                    .append(statistics.getTotalTickets())
                    .append(",")
                    .append(statistics.getCompletedCount())
                    .append(",")
                    .append(String.format("%.2f%%", statistics.getCompletionRate() * 100))
                    .append(",")
                    .append(statistics.getNoShowCount())
                    .append(",")
                    .append(String.format("%.2f%%", statistics.getNoShowRate() * 100))
                    .append(",")
                    .append(statistics.getAvgWaitTime())
                    .append(",")
                    .append(statistics.getAvgServiceTime())
                    .append(",")
                    .append(statistics.getPeakHour() != null ? statistics.getPeakHour() + ":00-" + (statistics.getPeakHour() + 1) + ":00" : "")
                    .append("\n");
        }
        
        return csvContent.toString();
    }
    
    @Override
    public byte[] exportStatisticsToExcel(StatisticsRequest request) {
        // 获取统计数据
        List<StatisticsResponse> statisticsList = getStatistics(request);
        
        if (CollUtil.isEmpty(statisticsList)) {
            return new byte[0];
        }
        
        // 创建Excel工作簿
        ExcelWriter writer = ExcelUtil.getWriter(true);
        
        // 设置列宽
        writer.setColumnWidth(0, 15);
        writer.setColumnWidth(1, 20);
        writer.setColumnWidth(2, 10);
        writer.setColumnWidth(3, 10);
        writer.setColumnWidth(4, 10);
        writer.setColumnWidth(5, 10);
        writer.setColumnWidth(6, 10);
        writer.setColumnWidth(7, 20);
        writer.setColumnWidth(8, 20);
        writer.setColumnWidth(9, 15);
        
        // 设置表头
        writer.addHeaderAlias("statDateStr", "日期");
        writer.addHeaderAlias("serviceTypeName", "业务类型");
        writer.addHeaderAlias("totalTickets", "总票数");
        writer.addHeaderAlias("completedCount", "已完成数");
        writer.addHeaderAlias("completionRateStr", "完成率");
        writer.addHeaderAlias("noShowCount", "未到场数");
        writer.addHeaderAlias("noShowRateStr", "未到场率");
        writer.addHeaderAlias("avgWaitTime", "平均等待时间(分钟)");
        writer.addHeaderAlias("avgServiceTime", "平均服务时间(分钟)");
        writer.addHeaderAlias("peakHourStr", "高峰时段");
        
        // 处理数据
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        List<Map<String, Object>> rows = new ArrayList<>();
        
        for (StatisticsResponse statistics : statisticsList) {
            Map<String, Object> row = new HashMap<>();
            row.put("statDateStr", statistics.getStatDate() != null ? statistics.getStatDate().format(dateFormatter) : "");
            row.put("serviceTypeName", StrUtil.isNotBlank(statistics.getServiceTypeName()) ? statistics.getServiceTypeName() : "全部");
            row.put("totalTickets", statistics.getTotalTickets());
            row.put("completedCount", statistics.getCompletedCount());
            row.put("completionRateStr", String.format("%.2f%%", statistics.getCompletionRate() * 100));
            row.put("noShowCount", statistics.getNoShowCount());
            row.put("noShowRateStr", String.format("%.2f%%", statistics.getNoShowRate() * 100));
            row.put("avgWaitTime", statistics.getAvgWaitTime());
            row.put("avgServiceTime", statistics.getAvgServiceTime());
            row.put("peakHourStr", statistics.getPeakHour() != null ? 
                    statistics.getPeakHour() + ":00-" + (statistics.getPeakHour() + 1) + ":00" : "");
            
            rows.add(row);
        }
        
        // 写入数据
        writer.write(rows, true);
        
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            writer.flush(outputStream, true);
            writer.close();
            byte[] result = outputStream.toByteArray();
            IoUtil.close(outputStream);
            return result;
        } catch (Exception e) {
            log.error("导出Excel失败", e);
            IoUtil.close(outputStream);
            throw new BusinessException(ResultCode.EXPORT_FAILED);
        }
    }
    
    @Override
    public StatisticsResponse getCurrentStatistics() {
        // 获取当日日期
        LocalDate today = LocalDate.now();
        LocalDateTime startOfDay = LocalDateTime.of(today, LocalTime.MIN);
        LocalDateTime now = LocalDateTime.now();
        
        // 查询当日所有队列记录
        LambdaQueryWrapper<Queue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.between(Queue::getCreateTime, startOfDay, now);
        
        List<Queue> queueList = queueMapper.selectList(queryWrapper);
        
        if (queueList.isEmpty()) {
            // 没有数据，返回空统计
            return StatisticsResponse.builder()
                    .statDate(today)
                    .totalTickets(0)
                    .completedCount(0)
                    .noShowCount(0)
                    .completionRate(0.0)
                    .noShowRate(0.0)
                    .avgWaitTime(0)
                    .avgServiceTime(0)
                    .build();
        }
        
        // 统计当前数据
        int totalTickets = queueList.size();
        long completedCount = queueList.stream()
                .filter(q -> "COMPLETED".equals(q.getStatus()))
                .count();
        
        long noShowCount = queueList.stream()
                .filter(q -> "NO_SHOW".equals(q.getStatus()))
                .count();
        
        // 计算平均等待时间和服务时间
        double avgWaitTime = queueList.stream()
                .filter(q -> q.getWaitTime() != null && q.getWaitTime() > 0)
                .mapToInt(Queue::getWaitTime)
                .average()
                .orElse(0);
        
        double avgServiceTime = queueList.stream()
                .filter(q -> q.getServiceTime() != null && q.getServiceTime() > 0)
                .mapToInt(Queue::getServiceTime)
                .average()
                .orElse(0);
        
        // 计算完成率和未到场率
        double completionRate = totalTickets > 0 ? (double) completedCount / totalTickets : 0;
        double noShowRate = totalTickets > 0 ? (double) noShowCount / totalTickets : 0;
        
        // 计算高峰时段
        Map<Integer, Long> hourDistribution = queueList.stream()
                .collect(Collectors.groupingBy(q -> q.getCreateTime().getHour(), Collectors.counting()));
        
        int peakHour = hourDistribution.entrySet().stream()
                .max(Map.Entry.comparingByValue())
                .map(Map.Entry::getKey)
                .orElse(0);
        
        // 获取当前各业务类型的等待人数
        Map<Long, Integer> waitingCountByType = new HashMap<>();
        for (ServiceType serviceType : serviceTypeMapper.selectActiveTypes()) {
            int waitingCount = queueMapper.countWaitingByServiceType(serviceType.getId());
            waitingCountByType.put(serviceType.getId(), waitingCount);
        }
        
        // 构建统计响应
        return StatisticsResponse.builder()
                .statDate(today)
                .totalTickets(totalTickets)
                .completedCount((int) completedCount)
                .completionRate(completionRate)
                .noShowCount((int) noShowCount)
                .noShowRate(noShowRate)
                .avgWaitTime((int) Math.round(avgWaitTime))
                .avgServiceTime((int) Math.round(avgServiceTime))
                .peakHour(peakHour)
                .hourlyDistribution(convertHourlyDistribution(hourDistribution))
                .build();
    }
    
    /**
     * 将统计实体列表转换为响应对象列表
     */
    private List<StatisticsResponse> convertToResponseList(List<Statistics> statisticsList) {
        if (CollUtil.isEmpty(statisticsList)) {
            return new ArrayList<>();
        }
        
        // 获取业务类型名称映射
        List<ServiceType> serviceTypes = serviceTypeMapper.selectList(null);
        Map<Long, String> serviceTypeNames = serviceTypes.stream()
                .collect(Collectors.toMap(ServiceType::getId, ServiceType::getName));
        
        // 转换为响应对象
        return statisticsList.stream()
                .map(statistics -> {
                    StatisticsResponse response = new StatisticsResponse();
                    BeanUtil.copyProperties(statistics, response);
                    
                    // 设置业务类型名称
                    String serviceTypeName = serviceTypeNames.getOrDefault(statistics.getServiceTypeId(), "未知业务类型");
                    response.setServiceTypeName(serviceTypeName);
                    
                    // 计算完成率和未到场率
                    double completionRate = statistics.getTotalTickets() > 0 ? 
                            (double) statistics.getCompletedCount() / statistics.getTotalTickets() : 0;
                    double noShowRate = statistics.getTotalTickets() > 0 ? 
                            (double) statistics.getNoShowCount() / statistics.getTotalTickets() : 0;
                    
                    response.setCompletionRate(completionRate);
                    response.setNoShowRate(noShowRate);
                    
                    return response;
                })
                .collect(Collectors.toList());
    }
    
    /**
     * 将小时分布转换为Map
     */
    private Map<Integer, Integer> convertHourlyDistribution(Map<Integer, Long> hourDistribution) {
        Map<Integer, Integer> result = new HashMap<>();
        for (Map.Entry<Integer, Long> entry : hourDistribution.entrySet()) {
            result.put(entry.getKey(), entry.getValue().intValue());
        }
        return result;
    }

    @Override
    public void updateStaffStats(Long staffId, String statsDate, Map<String, Object> metrics) {
        log.info("更新员工统计数据: staffId={}, statsDate={}, metrics={}", staffId, statsDate, metrics);
        
        try {
            // 先查询是否存在
            LambdaQueryWrapper<Statistics> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Statistics::getStaffId, staffId)
                    .eq(Statistics::getStatDate, statsDate);
            
            Statistics statistics = getOne(queryWrapper);
            
            if (statistics == null) {
                // 创建新记录
                statistics = new Statistics();
                statistics.setStaffId(staffId);
                statistics.setStatDate(LocalDate.parse(statsDate));
                statistics.setCreateTime(LocalDateTime.now());
            }
            
            // 更新统计数据
            if (metrics.containsKey("totalTickets")) {
                statistics.setTotalTickets(((Number) metrics.get("totalTickets")).intValue());
            }
            
            if (metrics.containsKey("completedCount")) {
                statistics.setCompletedCount(((Number) metrics.get("completedCount")).intValue());
            }
            
            if (metrics.containsKey("noShowCount")) {
                statistics.setNoShowCount(((Number) metrics.get("noShowCount")).intValue());
            }
            
            if (metrics.containsKey("avgWaitTime")) {
                statistics.setAvgWaitTime(((Number) metrics.get("avgWaitTime")).intValue());
            }
            
            if (metrics.containsKey("avgServiceTime")) {
                statistics.setAvgServiceTime(((Number) metrics.get("avgServiceTime")).intValue());
            }
            
            statistics.setUpdateTime(LocalDateTime.now());
            
            // 保存或更新
            saveOrUpdate(statistics);
            
        } catch (Exception e) {
            log.error("更新员工统计数据失败", e);
        }
    }

    @Override
    public void updateServiceTypeStats(Long serviceTypeId, String statsDate, Map<String, Object> metrics) {
        log.info("更新业务类型统计数据: serviceTypeId={}, statsDate={}, metrics={}", serviceTypeId, statsDate, metrics);
        
        try {
            // 先查询是否存在
            LambdaQueryWrapper<Statistics> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Statistics::getServiceTypeId, serviceTypeId)
                    .eq(Statistics::getStatDate, statsDate);
            
            Statistics statistics = getOne(queryWrapper);
            
            if (statistics == null) {
                // 创建新记录
                statistics = new Statistics();
                statistics.setServiceTypeId(serviceTypeId);
                statistics.setStatDate(LocalDate.parse(statsDate));
                statistics.setCreateTime(LocalDateTime.now());
            }
            
            // 更新统计数据
            if (metrics.containsKey("totalTickets")) {
                statistics.setTotalTickets(((Number) metrics.get("totalTickets")).intValue());
            }
            
            if (metrics.containsKey("completedCount")) {
                statistics.setCompletedCount(((Number) metrics.get("completedCount")).intValue());
            }
            
            if (metrics.containsKey("noShowCount")) {
                statistics.setNoShowCount(((Number) metrics.get("noShowCount")).intValue());
            }
            
            if (metrics.containsKey("avgWaitTime")) {
                statistics.setAvgWaitTime(((Number) metrics.get("avgWaitTime")).intValue());
            }
            
            if (metrics.containsKey("avgServiceTime")) {
                statistics.setAvgServiceTime(((Number) metrics.get("avgServiceTime")).intValue());
            }

            if (metrics.containsKey("waitingCount")) {
                statistics.setWaitingCount(((Number) metrics.get("waitingCount")).intValue());
            }
            
            statistics.setUpdateTime(LocalDateTime.now());
            
            // 保存或更新
            saveOrUpdate(statistics);
            
        } catch (Exception e) {
            log.error("更新业务类型统计数据失败", e);
        }
    }

    @Override
    public void updateWindowStats(Long windowId, String statsDate, Map<String, Object> metrics) {
        log.info("更新窗口统计数据: windowId={}, statsDate={}, metrics={}", windowId, statsDate, metrics);
        
        try {
            // 先查询是否存在
            LambdaQueryWrapper<Statistics> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Statistics::getWindowId, windowId)
                    .eq(Statistics::getStatDate, statsDate);
            
            Statistics statistics = getOne(queryWrapper);
            
            if (statistics == null) {
                // 创建新记录
                statistics = new Statistics();
                statistics.setWindowId(windowId);
                statistics.setStatDate(LocalDate.parse(statsDate));
                statistics.setCreateTime(LocalDateTime.now());
            }
            
            // 更新统计数据
            if (metrics.containsKey("totalTickets")) {
                statistics.setTotalTickets(((Number) metrics.get("totalTickets")).intValue());
            }
            
            if (metrics.containsKey("completedCount")) {
                statistics.setCompletedCount(((Number) metrics.get("completedCount")).intValue());
            }
            
            if (metrics.containsKey("noShowCount")) {
                statistics.setNoShowCount(((Number) metrics.get("noShowCount")).intValue());
            }
            
            if (metrics.containsKey("avgWaitTime")) {
                statistics.setAvgWaitTime(((Number) metrics.get("avgWaitTime")).intValue());
            }
            
            if (metrics.containsKey("avgServiceTime")) {
                statistics.setAvgServiceTime(((Number) metrics.get("avgServiceTime")).intValue());
            }
            
            statistics.setUpdateTime(LocalDateTime.now());
            
            // 保存或更新
            saveOrUpdate(statistics);
            
        } catch (Exception e) {
            log.error("更新窗口统计数据失败", e);
        }
    }

    @Override
    public void updateDailyStats(String statsDate, Map<String, Object> metrics) {
        log.info("更新每日统计数据: statsDate={}, metrics={}", statsDate, metrics);
        
        try {
            // 先查询是否存在
            LambdaQueryWrapper<Statistics> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Statistics::getStatDate, statsDate)
                    .isNull(Statistics::getServiceTypeId)
                    .isNull(Statistics::getWindowId)
                    .isNull(Statistics::getStaffId);
            
            Statistics statistics = getOne(queryWrapper);
            
            if (statistics == null) {
                // 创建新记录
                statistics = new Statistics();
                statistics.setStatDate(LocalDate.parse(statsDate));
                statistics.setCreateTime(LocalDateTime.now());
            }
            
            // 更新统计数据
            if (metrics.containsKey("totalTickets")) {
                statistics.setTotalTickets(((Number) metrics.get("totalTickets")).intValue());
            }
            
            if (metrics.containsKey("completedCount")) {
                statistics.setCompletedCount(((Number) metrics.get("completedCount")).intValue());
            }
            
            if (metrics.containsKey("noShowCount")) {
                statistics.setNoShowCount(((Number) metrics.get("noShowCount")).intValue());
            }
            
            if (metrics.containsKey("avgWaitTime")) {
                statistics.setAvgWaitTime(((Number) metrics.get("avgWaitTime")).intValue());
            }
            
            if (metrics.containsKey("avgServiceTime")) {
                statistics.setAvgServiceTime(((Number) metrics.get("avgServiceTime")).intValue());
            }
            
            statistics.setUpdateTime(LocalDateTime.now());
            
            // 保存或更新
            saveOrUpdate(statistics);
            
        } catch (Exception e) {
            log.error("更新每日统计数据失败", e);
        }
    }

    @Override
    public void updateWaitingCount(Long serviceTypeId) {
        log.info("更新等待人数统计: serviceTypeId={}", serviceTypeId);
        
        try {
            // 今日日期
            String today = LocalDate.now().toString();
            // 更新业务类型统计
            Map<String, Object> metrics = new HashMap<>();


            LambdaQueryWrapper<Queue> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Queue::getServiceTypeId, serviceTypeId)
                    .ge(Queue::getCreateTime, today);
            List<Queue> queues = queueMapper.selectList(queryWrapper);
            AtomicInteger waitingCount = new AtomicInteger();
            AtomicInteger completedCount = new AtomicInteger();
            AtomicInteger noShowCount = new AtomicInteger();
            AtomicReference<Long> totalAvgWaitTime = new AtomicReference<>(0L);
            AtomicReference<Long> totalServiceTime = new AtomicReference<>(0L);
            queues.forEach(queue -> {
                if (Objects.equals(queue.getStatus(), "WAITING")) {
                    waitingCount.getAndIncrement();
                } else if (Objects.equals(queue.getStatus(), "COMPLETED")){
                    completedCount.getAndIncrement();
                    totalAvgWaitTime.updateAndGet(v -> v + DateUtil.between(new DateTime(queue.getCallTime()),
                            new DateTime(queue.getCreateTime()), DateUnit.MINUTE));
                    totalServiceTime.updateAndGet(v -> v + DateUtil.between(new DateTime(queue.getCallTime()),
                            new DateTime(queue.getEndTime()), DateUnit.MINUTE));
                } else if (Objects.equals(queue.getStatus(), "NO_SHOW")) {
                    noShowCount.getAndIncrement();
                }
            });

            metrics.put("totalTickets", queues.size());
            metrics.put("completedCount", completedCount.get());
            metrics.put("noShowCount", noShowCount.get());
            metrics.put("avgWaitTime",completedCount.get() == 0 ? 0 : totalAvgWaitTime.get() / completedCount.get());
            metrics.put("avgServiceTime", completedCount.get() == 0 ? 0 : totalServiceTime.get() / completedCount.get());
            metrics.put("waitingCount", waitingCount.get());
            updateServiceTypeStats(serviceTypeId, today, metrics);
        } catch (Exception e) {
            log.error("更新等待人数统计失败", e);
        }
    }

    @Override
    public void updateCallStats(Long serviceTypeId, Long windowId) {
        log.info("更新叫号统计: serviceTypeId={}, windowId={}", serviceTypeId, windowId);
        
        try {
            // 今日日期
            String today = LocalDate.now().toString();
            
            // 更新业务类型统计
            Map<String, Object> typeMetrics = new HashMap<>();
            typeMetrics.put("callCount", 1);
            updateServiceTypeStats(serviceTypeId, today, typeMetrics);
            
            // 更新窗口统计
            Map<String, Object> windowMetrics = new HashMap<>();
            windowMetrics.put("callCount", 1);
            updateWindowStats(windowId, today, windowMetrics);
            
        } catch (Exception e) {
            log.error("更新叫号统计失败", e);
        }
    }

    @Override
    public void updateServiceStats(Long serviceTypeId, Long windowId, Integer processingTime, Integer waitingTime) {
        log.info("更新服务统计: serviceTypeId={}, windowId={}, processingTime={}, waitingTime={}", 
                serviceTypeId, windowId, processingTime, waitingTime);
        
        try {
            // 今日日期
            String today = LocalDate.now().toString();
            
            // 窗口统计
            Window window = windowMapper.selectById(windowId);
            Long staffId = window != null ? window.getStaffId() : null;
            
            // 更新业务类型统计
            Map<String, Object> typeMetrics = new HashMap<>();
            typeMetrics.put("completedCount", 1);
            typeMetrics.put("avgServiceTime", processingTime);
            typeMetrics.put("avgWaitTime", waitingTime);
            updateServiceTypeStats(serviceTypeId, today, typeMetrics);
            
            // 更新窗口统计
            Map<String, Object> windowMetrics = new HashMap<>();
            windowMetrics.put("completedCount", 1);
            windowMetrics.put("avgServiceTime", processingTime);
            windowMetrics.put("avgWaitTime", waitingTime);
            updateWindowStats(windowId, today, windowMetrics);
            
            // 更新员工统计
            if (staffId != null) {
                Map<String, Object> staffMetrics = new HashMap<>();
                staffMetrics.put("completedCount", 1);
                staffMetrics.put("avgServiceTime", processingTime);
                staffMetrics.put("avgWaitTime", waitingTime);
                updateStaffStats(staffId, today, staffMetrics);
            }
            
            // 更新每日总统计
            Map<String, Object> dailyMetrics = new HashMap<>();
            dailyMetrics.put("completedCount", 1);
            dailyMetrics.put("avgServiceTime", processingTime);
            dailyMetrics.put("avgWaitTime", waitingTime);
            updateDailyStats(today, dailyMetrics);
            
        } catch (Exception e) {
            log.error("更新服务统计失败", e);
        }
    }

    @Override
    public StatisticsResponse getOverallStatistics(StatisticsRequest request) {
        // 默认返回今日统计
        if (request.getStartDate() == null) {
            request.setStartDate(LocalDate.now());
        }
        if (request.getEndDate() == null) {
            request.setEndDate(LocalDate.now());
        }
        
        // 查询日期范围内的统计数据
        List<Statistics> statisticsList = statisticsMapper.selectByDateRange(
                request.getStartDate(), request.getEndDate());
        
        if (statisticsList.isEmpty()) {
            return StatisticsResponse.builder().build();
        }
        
        // 汇总统计数据
        int totalTickets = statisticsList.stream().mapToInt(Statistics::getTotalTickets).sum();
        int completedCount = statisticsList.stream().mapToInt(Statistics::getCompletedCount).sum();
        int noShowCount = statisticsList.stream().mapToInt(Statistics::getNoShowCount).sum();
        
        double avgWaitTime = statisticsList.stream()
                .filter(s -> s.getAvgWaitTime() != null && s.getAvgWaitTime() > 0)
                .mapToInt(Statistics::getAvgWaitTime)
                .average()
                .orElse(0);
        
        double avgServiceTime = statisticsList.stream()
                .filter(s -> s.getAvgServiceTime() != null && s.getAvgServiceTime() > 0)
                .mapToInt(Statistics::getAvgServiceTime)
                .average()
                .orElse(0);
        
        // 计算完成率和未到场率
        double completionRate = totalTickets > 0 ? (double) completedCount / totalTickets : 0;
        double noShowRate = totalTickets > 0 ? (double) noShowCount / totalTickets : 0;
        
        return StatisticsResponse.builder()
                .totalTickets(totalTickets)
                .completedCount(completedCount)
                .completionRate(completionRate)
                .noShowCount(noShowCount)
                .noShowRate(noShowRate)
                .avgWaitTime((int) Math.round(avgWaitTime))
                .avgServiceTime((int) Math.round(avgServiceTime))
                .build();
    }

    @Override
    public StatisticsResponse getServiceTypeStatistics(StatisticsRequest request) {
        if (request.getServiceTypeId() == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "业务类型ID不能为空");
        }
        
        // 默认返回今日统计
        if (request.getStartDate() == null) {
            request.setStartDate(LocalDate.now());
        }
        if (request.getEndDate() == null) {
            request.setEndDate(LocalDate.now());
        }
        
        // 查询业务类型信息
        ServiceType serviceType = serviceTypeMapper.selectById(request.getServiceTypeId());
        if (serviceType == null) {
            throw new BusinessException(ResultCode.BUSINESS_TYPE_NOT_FOUND);
        }
        
        // 查询日期范围内的统计数据
        List<Statistics> statisticsList = statisticsMapper.selectByDateRangeAndServiceType(
                request.getStartDate(), request.getEndDate(), request.getServiceTypeId());
        
        if (statisticsList.isEmpty()) {
            return StatisticsResponse.builder()
                    .serviceTypeId(request.getServiceTypeId())
                    .serviceTypeName(serviceType.getName())
                    .build();
        }
        
        // 汇总统计数据
        int totalTickets = statisticsList.stream().mapToInt(Statistics::getTotalTickets).sum();
        int completedCount = statisticsList.stream().mapToInt(Statistics::getCompletedCount).sum();
        int noShowCount = statisticsList.stream().mapToInt(Statistics::getNoShowCount).sum();
        
        double avgWaitTime = statisticsList.stream()
                .filter(s -> s.getAvgWaitTime() != null && s.getAvgWaitTime() > 0)
                .mapToInt(Statistics::getAvgWaitTime)
                .average()
                .orElse(0);
        
        double avgServiceTime = statisticsList.stream()
                .filter(s -> s.getAvgServiceTime() != null && s.getAvgServiceTime() > 0)
                .mapToInt(Statistics::getAvgServiceTime)
                .average()
                .orElse(0);
        
        // 计算完成率和未到场率
        double completionRate = totalTickets > 0 ? (double) completedCount / totalTickets : 0;
        double noShowRate = totalTickets > 0 ? (double) noShowCount / totalTickets : 0;
        
        return StatisticsResponse.builder()
                .serviceTypeId(request.getServiceTypeId())
                .serviceTypeName(serviceType.getName())
                .totalTickets(totalTickets)
                .completedCount(completedCount)
                .completionRate(completionRate)
                .noShowCount(noShowCount)
                .noShowRate(noShowRate)
                .avgWaitTime((int) Math.round(avgWaitTime))
                .avgServiceTime((int) Math.round(avgServiceTime))
                .build();
    }

    @Override
    public StatisticsResponse getWindowStatistics(StatisticsRequest request) {
        if (request.getWindowId() == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "窗口ID不能为空");
        }
        
        // 查询窗口信息
        Window window = windowMapper.selectById(request.getWindowId());
        if (window == null) {
            throw new BusinessException(ResultCode.WINDOW_NOT_FOUND);
        }
        
        // 获取窗口统计数据
        Map<Long, StatisticsResponse> windowStatistics = getStatisticsByWindow(
                request.getStartDate(), request.getEndDate());
        
        StatisticsResponse response = windowStatistics.get(request.getWindowId());
        if (response == null) {
            return StatisticsResponse.builder()
                    .windowId(request.getWindowId())
                    .windowName(window.getName())
                    .build();
        }
        
        return response;
    }

    @Override
    public StatisticsResponse getStaffStatistics(StatisticsRequest request) {
        if (request.getStaffId() == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "员工ID不能为空");
        }
        
        // 默认返回今日统计
        if (request.getStartDate() == null) {
            request.setStartDate(LocalDate.now());
        }
        if (request.getEndDate() == null) {
            request.setEndDate(LocalDate.now());
        }
        
        // 查询日期范围内的统计数据
        LambdaQueryWrapper<Statistics> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Statistics::getStaffId, request.getStaffId())
                .between(Statistics::getStatDate, request.getStartDate(), request.getEndDate());
        
        List<Statistics> statisticsList = list(queryWrapper);
        
        if (statisticsList.isEmpty()) {
            return StatisticsResponse.builder()
                    .staffId(request.getStaffId())
                    .build();
        }
        
        // 汇总统计数据
        int totalTickets = statisticsList.stream().mapToInt(Statistics::getTotalTickets).sum();
        int completedCount = statisticsList.stream().mapToInt(Statistics::getCompletedCount).sum();
        int noShowCount = statisticsList.stream().mapToInt(Statistics::getNoShowCount).sum();
        
        double avgWaitTime = statisticsList.stream()
                .filter(s -> s.getAvgWaitTime() != null && s.getAvgWaitTime() > 0)
                .mapToInt(Statistics::getAvgWaitTime)
                .average()
                .orElse(0);
        
        double avgServiceTime = statisticsList.stream()
                .filter(s -> s.getAvgServiceTime() != null && s.getAvgServiceTime() > 0)
                .mapToInt(Statistics::getAvgServiceTime)
                .average()
                .orElse(0);
        
        // 计算完成率和未到场率
        double completionRate = totalTickets > 0 ? (double) completedCount / totalTickets : 0;
        double noShowRate = totalTickets > 0 ? (double) noShowCount / totalTickets : 0;
        
        return StatisticsResponse.builder()
                .staffId(request.getStaffId())
                .totalTickets(totalTickets)
                .completedCount(completedCount)
                .completionRate(completionRate)
                .noShowCount(noShowCount)
                .noShowRate(noShowRate)
                .avgWaitTime((int) Math.round(avgWaitTime))
                .avgServiceTime((int) Math.round(avgServiceTime))
                .build();
    }

    @Override
    public Map<String, Object> getRealTimeStatistics() {
        Map<String, Object> result = new HashMap<>();
        
        // 今日日期
        LocalDate today = LocalDate.now();
        
        // 查询今日统计数据
        LambdaQueryWrapper<Statistics> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Statistics::getStatDate, today);
        
        List<Statistics> statisticsList = list(queryWrapper);
        
        // 统计总体数据
        int totalTickets = statisticsList.stream().mapToInt(Statistics::getTotalTickets).sum();
        int completedCount = statisticsList.stream().mapToInt(Statistics::getCompletedCount).sum();
        int waitingCount = totalTickets - completedCount;
        
        result.put("totalTickets", totalTickets);
        result.put("completedCount", completedCount);
        result.put("waitingCount", waitingCount);
        
        // 查询业务类型数据
        Map<Long, ServiceType> serviceTypeMap = serviceTypeMapper.selectList(null).stream()
                .collect(Collectors.toMap(ServiceType::getId, serviceType -> serviceType));
        
        // 按业务类型统计数据
        Map<Long, Map<String, Object>> serviceTypeStats = new HashMap<>();
        for (Statistics stats : statisticsList) {
            if (stats.getServiceTypeId() != null) {
                Map<String, Object> typeStats = new HashMap<>();
                typeStats.put("serviceTypeId", stats.getServiceTypeId());
                typeStats.put("serviceTypeName", serviceTypeMap.containsKey(stats.getServiceTypeId()) ? 
                        serviceTypeMap.get(stats.getServiceTypeId()).getName() : "未知业务类型");
                typeStats.put("totalTickets", stats.getTotalTickets());
                typeStats.put("completedCount", stats.getCompletedCount());
                typeStats.put("waitingCount", stats.getTotalTickets() - stats.getCompletedCount());
                
                serviceTypeStats.put(stats.getServiceTypeId(), typeStats);
            }
        }
        
        result.put("serviceTypeStats", serviceTypeStats.values());
        
        return result;
    }

    @Override
    public PageResult<Map<String, Object>> getHistoricalStatistics(PageRequest pageRequest) {
        // 查询历史统计数据
        LambdaQueryWrapper<Statistics> queryWrapper = new LambdaQueryWrapper<>();
        
        // 处理过滤条件
        if (pageRequest.getFilters() != null) {
            if (pageRequest.getFilters().containsKey("serviceTypeId")) {
                Object serviceTypeId = pageRequest.getFilters().get("serviceTypeId");
                if (serviceTypeId != null) {
                    queryWrapper.eq(Statistics::getServiceTypeId, serviceTypeId);
                }
            }
            
            if (pageRequest.getFilters().containsKey("startDate")) {
                Object startDateObj = pageRequest.getFilters().get("startDate");
                if (startDateObj != null) {
                    LocalDate startDate = LocalDate.parse(startDateObj.toString());
                    queryWrapper.ge(Statistics::getStatDate, startDate);
                }
            }
            
            if (pageRequest.getFilters().containsKey("endDate")) {
                Object endDateObj = pageRequest.getFilters().get("endDate");
                if (endDateObj != null) {
                    LocalDate endDate = LocalDate.parse(endDateObj.toString());
                    queryWrapper.le(Statistics::getStatDate, endDate);
                }
            }
        }
        
        // 处理排序
        if (StrUtil.isNotBlank(pageRequest.getOrderBy())) {
            if ("statDate".equals(pageRequest.getOrderBy())) {
                queryWrapper.orderBy(true, pageRequest.getIsAsc(), Statistics::getStatDate);
            } else if ("totalTickets".equals(pageRequest.getOrderBy())) {
                queryWrapper.orderBy(true, pageRequest.getIsAsc(), Statistics::getTotalTickets);
            } else if ("completedCount".equals(pageRequest.getOrderBy())) {
                queryWrapper.orderBy(true, pageRequest.getIsAsc(), Statistics::getCompletedCount);
            }
        } else {
            // 默认按统计日期倒序
            queryWrapper.orderByDesc(Statistics::getStatDate);
        }
        
        // 分页查询
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<Statistics> page = 
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(
                        pageRequest.getPageNum(), pageRequest.getPageSize());
        
        page = page(page, queryWrapper);
        
        // 转换结果
        List<Map<String, Object>> records = new ArrayList<>();
        
        for (Statistics stats : page.getRecords()) {
            Map<String, Object> record = new HashMap<>();
            record.put("id", stats.getId());
            record.put("statDate", stats.getStatDate().toString());
            record.put("serviceTypeId", stats.getServiceTypeId());
            record.put("windowId", stats.getWindowId());
            record.put("staffId", stats.getStaffId());
            record.put("totalTickets", stats.getTotalTickets());
            record.put("completedCount", stats.getCompletedCount());
            record.put("noShowCount", stats.getNoShowCount());
            record.put("avgWaitTime", stats.getAvgWaitTime());
            record.put("avgServiceTime", stats.getAvgServiceTime());
            
            records.add(record);
        }
        
        // 使用PageResult.builder方法创建
        return PageResult.<Map<String, Object>>builder()
                .pageNum(pageRequest.getPageNum())
                .pageSize(pageRequest.getPageSize())
                .total(page.getTotal())
                .pages((int) page.getPages())
                .list(records)
                .hasPrev(pageRequest.getPageNum() > 1)
                .hasNext(pageRequest.getPageNum() < page.getPages())
                .build();
    }

    @Override
    public String exportStatistics(StatisticsRequest request) {
        log.info("导出统计数据: request={}", request);
        
        try {
            // 根据请求的格式导出不同类型的文件
            if ("csv".equalsIgnoreCase(request.getFormat())) {
                return exportStatisticsToCSV(request);
            } else {
                // 默认导出Excel
                byte[] excelData = exportStatisticsToExcel(request);
                
                // 生成临时文件路径
                String fileName = "statistics_" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".xlsx";
                String tempFilePath = System.getProperty("java.io.tmpdir") + "/" + fileName;
                
                // 写入临时文件
                try {
                    java.nio.file.Files.write(java.nio.file.Paths.get(tempFilePath), excelData);
                    return tempFilePath;
                } catch (java.io.IOException e) {
                    log.error("写入临时文件失败", e);
                    throw new BusinessException(ResultCode.EXPORT_FAILED);
                }
            }
        } catch (Exception e) {
            log.error("导出统计数据失败", e);
            throw new BusinessException(ResultCode.EXPORT_FAILED);
        }
    }
} 